<?php

namespace App\Model;

use EasySwoole\Mysqli\QueryBuilder;

class MpInviteCodeModel
{
    private static string $table = 'brz_mp_qr_def_code';

    private function createNewCode(): int
    {
        try {
            $client = (new MysqliFactory())->createMysqlClient();
            $client->queryBuilder()
                ->orderBy('code', 'DESC')
                ->limit(1)
                ->getColumn(self::$table, 'code');
            $min = 10000;
            $ret = $client->execBuilder();
            $max = $ret[0]['code'] ?? $min;
            if ($max < $min) {
                $max = $min;
            }
            return $max + 1;

        } catch (\Throwable $e) {
            echo $e->getMessage(), PHP_EOL;
            echo $e->getLine(), PHP_EOL;
            return 0;
        }
    }

    public function getCode(int $uid, int $qid, string $openid): int
    {
        $client = (new MysqliFactory())->createMysqlClient();
        $client->queryBuilder()->where('qid', $qid)->where('uid', $uid)->getColumn(self::$table, 'code');
        try {
            $code = $client->execBuilder()[0]['code'] ?? 0;
            if ($code) {
                return $code;
            } else {
                $newCode = $this->createNewCode();
                $insert  = [
                    'qid'      => $qid,
                    'openid'   => $openid,
                    'uid'      => $uid,
                    'code'     => $newCode,
                    'add_time' => time(),
                ];
                $client->queryBuilder()->insert(self::$table, $insert);
                $client->execBuilder();
                return $newCode;
            }

        } catch (\Throwable $e) {
            echo $e->getMessage(), PHP_EOL;
            return 0;
        }
    }

    public function findByCode(int $code, array $fields)
    {
        $client = (new MysqliFactory())->createMysqlClient();
        $client->queryBuilder()->where('code', $code)->fields($fields)->limit(1)->get(self::$table);
        try {
            $ret = $client->execBuilder();

            if (!$ret) {
                return [];
            }
            return $ret[0];
        } catch (\Throwable $e) {
            echo $e->getMessage();
            return null;
        }
    }

    private function changeInvitedCount(int $code, string $act)
    {
        try {
            $fieldValue = $act === 'incr' ? QueryBuilder::inc(1) : QueryBuilder::dec(1);
            $client     = (new MysqliFactory())->createMysqlClient();
            $field      = 'invite_count';
            $client->queryBuilder()
                ->where('code', $code)
                ->update(self::$table, [$field => $fieldValue]);
            $client->execBuilder();
            $client->queryBuilder()->where('code', $code)->getColumn(self::$table, [$field])->getField();
            $ret = $client->execBuilder();
            return (int)$ret[0][$field];
        } catch (\Throwable $e) {
            echo $e->getMessage(), PHP_EOL;
            return 0;
        }
    }

    /**
     * 增加用户的助力数，并返回增加后的助力数
     * @param int $code
     * @return int
     */
    public function incrInvitedCountByCode(int $code)
    {
        return $this->changeInvitedCount($code, 'incr');
    }

    /**
     * 减少用户的助力数，并返回增加后的助力数
     * @param int $code
     * @return int
     */
    public function decrInvitedCountByCode(int $code)
    {
        return $this->changeInvitedCount($code, 'decr');
    }

    public function setIsComplete(int $code, bool $isComplete = true)
    {
        $client = (new MysqliFactory())->createMysqlClient();
        $client->queryBuilder()->where('code', $code)->update(self::$table, ['is_complete' => $isComplete ? 1 : 0, 'complete_time' => time()]);
        try {
            $client->execBuilder();
        } catch (\Throwable $e) {
            echo $e->getMessage(), PHP_EOL;
        }
    }

}

